// This is the main DLL file.

#include "stdafx.h"
#include "Connect.h"
#include "Log.h"
#include <vcclr.h>

using namespace System::Runtime::InteropServices;
using namespace System::Collections;

Reviewboard::Connect::Connect()
{
	ArcInitializeLogSystemW(L"log4cpp.property");
}

Reviewboard::Connect::~Connect()
{
	//ArcUnInitializeLogSystem();
}

void Reviewboard::Connect::OnAddInsUpdate(System::Array ^%custom)
{
}

void Reviewboard::Connect::OnBeginShutdown(System::Array ^%custom)
{
}

void Reviewboard::Connect::OnConnection(System::Object ^Application, ext_ConnectMode ConnectMode, System::Object ^AddInInst, System::Array ^%custom)
{
    _applicationObject = dynamic_cast<DTE2^>(Application);
    _addInInstance = dynamic_cast<AddIn^>(AddInInst);
	if(ConnectMode == ext_ConnectMode::ext_cm_Startup)
    {
        array< Object^ >^ contextGUIDs = gcnew array< Object^ >(0);
        Commands2 ^commands = dynamic_cast<Commands2^>(_applicationObject->Commands);
		
		CommandBars^ cmdBars = (CommandBars^)(_applicationObject->CommandBars); 
		
        try
        {	
            //Add a command to the Commands collection:
            Command ^command = commands->AddNamedCommand2(
				_addInInstance, 
				"Reviewboard", 
				"Reviewboard...", 
				"Executes the command for Reviewboard", 
				true, 
				59, 
				contextGUIDs, 
				(int)vsCommandStatus::vsCommandStatusSupported+
					(int)vsCommandStatus::vsCommandStatusEnabled,
				(int)vsCommandStyle::vsCommandStylePictAndText, 
				vsCommandControlType::vsCommandControlTypeMRUButton );
			
            //Add a control for the command to the tools menu:
            if((command))
			{
				CommandBar^ bar;
				bar = cmdBars["Project"]; 
				command->AddControl(bar, 1);
				bar = cmdBars["Solution"];
				command->AddControl(bar, 1);
				bar = cmdBars["Item"];
				command->AddControl(bar,1);
				bar= cmdBars["Folder"];
				command->AddControl(bar,1);
				//CommandBar^ mfpCB = cmdBars["Project and Solution Context Menus"];
				//command->AddControl(mfpCB,1);
				bar = cmdBars["Cross Project Multi Project"];
				command->AddControl(bar,1);
				bar = cmdBars["Cross Project Multi Item"];
				command->AddControl(bar,1);
				bar= cmdBars["Cross Project Multi Project/Folder"];
				command->AddControl(bar,1);
				bar = cmdBars["Cross Project Multi Solution Folder"];
				command->AddControl(bar,1);
				bar = cmdBars["Cross Project Solution Project"];
				command->AddControl(bar,1);
				bar = cmdBars["Cross Project Project Item"];
				command->AddControl(bar,1);
				
				
            }

        }
		catch(System::ArgumentException ^)
        {
			
        }
    }
}

void Reviewboard::Connect::OnStartupComplete(System::Array ^%custom)
{
}

void Reviewboard::Connect::OnDisconnection(ext_DisconnectMode removeMode, System::Array ^%custom)
{
	using namespace System::Collections;
	if (removeMode == ext_DisconnectMode::ext_dm_HostShutdown ||
		removeMode == ext_DisconnectMode::ext_dm_UserClosed)
	{
		
		Commands^ comands = _applicationObject->Commands;
		IEnumerator^ e = comands->GetEnumerator();
		while(e->MoveNext())
		{
			Command^ command = (Command^)e->Current;
			String^ name = command->default;
			if (name == "Reviewboard.Connect.Reviewboard")
			{
				command->Delete();
			}
		}
	}
}


void Reviewboard::Connect::Exec(String ^CmdName, vsCommandExecOption ExecuteOption, Object ^%VariantIn, Object ^%VariantOut, bool %handled)
{
    handled = false;
    if(ExecuteOption == vsCommandExecOption::vsCommandExecOptionDoDefault)
    {
        if(!CmdName->CompareTo("Reviewboard.Connect.Reviewboard"))
        {

			SelectedItems^ selectItems = _applicationObject->SelectedItems;
			IEnumerator^ enumerator = selectItems->GetEnumerator();
			while (enumerator->MoveNext())
			{
				SelectedItem^ selectItem = (SelectedItem^)enumerator->Current;
				
				ProjectItem^ item = nullptr;
				if(selectItem->ProjectItem) 
				{
					item = selectItem->ProjectItem;

					IEnumerator^ extEnumerator =  item->Properties->GetEnumerator();
					while(extEnumerator->MoveNext())
					{
						Property^ p = (Property^)extEnumerator->Current;
						
						//pin_ptr<const wchar_t> itemName = PtrToStringChars( (String^)(item->default));
						//pin_ptr<const wchar_t> propertyName = PtrToStringChars( (String^)(p->Name));
						
						String^ value;
						try
						{
							value = (String^)(p->default);
						}
						catch (System::InvalidCastException ^)
						{
							value = "Unkown Object";
						}
						
						
						//pin_ptr<const wchar_t> name = PtrToStringChars(value);

						ArcLogW(LEVEL_DEBUG, L"project item:%s, property name: %s, value : %s", item->default, p->Name, value);
					}

					
				}
				
			}
			
            handled = true;
            return;
        }

    }
}

void Reviewboard::Connect::QueryStatus(String ^CmdName, vsCommandStatusTextWanted NeededText, vsCommandStatus %StatusOption, Object ^%CommandText)
{
    if(NeededText == vsCommandStatusTextWanted::vsCommandStatusTextWantedNone)
    {
        if(!CmdName->CompareTo("Reviewboard.Connect.Reviewboard"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
    }
}